package uage.compiler

import jdk.nashorn.internal.parser.TokenStream
import uage.ast._
import jdk.nashorn.internal.ir.WhileNode
import java.util.logging.Logger

class Tokenizer(val charIter:Iterator[Char]){
  var lastChar = 0
  var curChar = 0
  var curToken = (0,"")
  //var token:StringBuilder = new StringBuilder
  //val tokenStream = scala.collection.mutable.ListBuffer[(String,String)]()
  //0:空字符 9:水平制表符 10:换行键 11:垂直制表符 12:换页键 13:回车符 32:空格
  //val emptyChars = List(0,9,10,11,12,13,32)
  
  def getChar() = curChar.toChar
  
  def nextChar() = {
    if(charIter.hasNext) {
      lastChar = curChar
      curChar = charIter.next().toInt
    } else {
      curChar = -1
    }
  }
  
  def hasNext() = {
    charIter.hasNext
  }
  
  def nextToken():(Int,String) = {
    if(Character.isAlphabetic(getChar())){
      return parseIdentifier()
    }else if(Character.isDigit(getChar())){
      return parseNumber()
    }else if(getChar() == '"'){
      return parseString()
    }else if(getChar().toString().trim() == ""){
//      if(Character.isAlphabetic(lastChar) //e.g. symbol  () means (expr symbol) and (expr ()) not (expr symbol())
//          || lastChar == ')'){ //e.g. ()  {} means (expr ()) and (expr {}) not (expr (){})
//        nextChar() //eat
//        return (Identifier.SPACE," ")
//      } else {
//      }
      nextChar()
      return nextToken()
    } else {
      return parseOthers()
//      curToken = (curChar,getChar().toString())
//      nextChar()
//      return curToken
    }
  }
  
  def parseOthers() = { //e.g. , || ; || + || - || ++ || ...
    curToken = (curChar,getChar().toString()) //save
    if(getChar() == '+') {
      nextChar(); //eat '+'
      if(getChar() == '+'){ //e.g. ++
        nextChar() //eat '+'
        curToken = (Identifier.PLUSPLUS,"++")
      }
    } else if(getChar() == '-'){
      nextChar() //eat '-'
      if(getChar() == '-'){ //e.g. --
        nextChar() //eat '-'
        curToken = (Identifier.SUBSUB,"--") ///e.g. --
      } else if(getChar() == '>'){ //e.g. ->
        nextChar() //eat '>'
        curToken = (Identifier.RIGHT_ARROW,"->")
      }
    } else if(getChar() == '='){
      nextChar() //eat '='
      if(getChar() == '='){ //e.g. ==
        nextChar() //eat '='
        curToken = (Identifier.EQUAL,"==")
      } else if(getChar() == '>'){ //e.g. =>
        nextChar() //eat '>'
        curToken = (Identifier.EQUAL_ARROW,"=>")
      }
    } else if(getChar() == '>'){
      nextChar() //eat '>'
      if(getChar() == '='){ //e.g. >=
        nextChar() //eat '='
        curToken = (Identifier.NO_LESS_THAN,">=")
      }
    } else if(getChar() == '<'){
      nextChar() //eat '<'
      if(getChar() == '='){ //e.g. <=
        nextChar() //eat '='
        curToken = (Identifier.NO_MORE_THAN,"<=")
      } else if(getChar() == '-'){ //e.g. <-
        nextChar() //eat '-'
        curToken = (Identifier.LEFT_ARROW,"<-")
      }
    } else if(getChar() == '&'){
      nextChar() //eat '&'
      if(getChar() == '&'){ //e.g. &&
        nextChar()
        curToken = (Identifier.AND,"&&")
      }
    } else if(getChar() == '|'){
      nextChar() //eat '|'
      if(getChar() == '|'){ //e.g. ||
        nextChar()
        curToken = (Identifier.OR,"||")
      }
    } else if(getChar() == '!'){
      nextChar() //eat '!'
      if(getChar() == '='){ //e.g. !=
        nextChar()
        curToken = (Identifier.UNEQUAL,"!=")
      }
    }
    else{
      nextChar() //eat curChar
    }
    curToken
  }
  
  def parseIdentifier() = { //解析标识符 e.g. abc a34...
    var token = new StringBuffer
    token.append(getChar())
    nextChar()
    while(Character.isAlphabetic(curChar) || Character.isDigit(curChar)){
      token.append(curChar.toChar)
      nextChar()
    }
   
    curToken = (Identifier.SYMBOL,token.toString())
    curToken
  }
  
  def parseNumber() = {
    var token = new StringBuffer
    token.append(getChar())
    nextChar()
    while(Character.isDigit(curChar)){
      token.append(getChar())
      nextChar()
    }
    curToken = (Identifier.NUMBER,token.toString())
    curToken
  }
  
  def parseString() = {
    nextChar() //eat left of '"'
    var token = new StringBuffer()
    while(getChar() != '"'){
      token.append(getChar())
      nextChar()
    }
    nextChar() //eat right of '"'
    curToken = (Identifier.STRING,token.toString())
    curToken
  }
}